home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / util / wxpaste.c < prev   
Encoding:
C/C++ Source or Header  |  1999-01-29  |  6.1 KB  |  251 lines

  1. /* wxpaste.c- paste contents of cutbuffer to stdout
  2.  * 
  3.  *  Copyright (c) 1997 Alfredo K. Kojima
  4.  * 
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #define PROG_VERSION "wxpaste (Window Maker) 0.3"
  21.  
  22. #include "../src/config.h"
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <unistd.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include <X11/Xlib.h>
  30. #include <X11/Xatom.h>
  31. #include <sys/time.h>
  32. #include <sys/types.h>
  33. #ifdef HAVE_SYS_SELECT_H
  34. # include <sys/select.h>
  35. #endif
  36.  
  37.  
  38. #define MAXDATA        (4*1024*1024)
  39.  
  40.  
  41. void
  42. help(char *progn)
  43. {
  44.     printf("Usage: %s [OPTIONS] [FILE]\n", progn);
  45.     puts("Copies data from X selection or cutbuffer to FILE or stdout.");
  46.     puts("");
  47.     puts("  -display display        display to use");
  48.     puts("  --cutbuffer number        cutbuffer number to get data from");
  49.     puts("  --selection [selection]    reads data from named selection instead of\n"
  50.      "                cutbuffer");
  51.     puts("  --help            display this help and exit");
  52.     puts("  --version            output version information and exit");
  53. }
  54.  
  55.  
  56. Time
  57. getTimestamp(Display *dpy, Window win)
  58. {
  59.     XEvent ev;
  60.  
  61.     /* So we do this trickery to get a time stamp:
  62.      * 
  63.      * 1. Grab the server because we are paranoid and don't want to
  64.      * get in a race with another instance of wxpaste being ran at the
  65.      * same time.
  66.      * 
  67.      * 2. Set a dummy property in our window.
  68.      * 
  69.      * 3. Get the PropertyNotify event and get it's timestamp.
  70.      * 
  71.      * 4. Ungrab the server.
  72.      */
  73.  
  74.     XSelectInput(dpy, win, PropertyChangeMask);
  75.  
  76.     /* Generate a PropertyNotify event */
  77.     XStoreName(dpy, win, "shit");
  78.  
  79.     /* wait for the event */
  80.     while (1) {
  81.     XNextEvent(dpy, &ev);
  82.     if (ev.type == PropertyNotify)
  83.         break;
  84.     }
  85.  
  86.     return ev.xproperty.time;
  87. }
  88.  
  89.  
  90. char*
  91. fetchSelection(Display *dpy, char *selection, char *progName)
  92. {
  93.     Atom selatom = XInternAtom(dpy, selection, False);
  94.     Atom clipatom = XInternAtom(dpy, "CLIPBOARD", False);
  95.     Time now;
  96.     XEvent ev;
  97.     Window win;
  98.     int ok = 0;
  99.     struct timeval timeout;
  100.     fd_set fdset;
  101.  
  102.     win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1,
  103.                   0, 0, 0);
  104.     /* 
  105.      * The ICCCM says that we can't pass CurrentTime as the timestamp
  106.      * for XConvertSelection(), but we don't have anything to use as
  107.      * a timestamp...
  108.      */
  109.     now = getTimestamp(dpy, win);
  110.  
  111.     XConvertSelection(dpy, selatom, XA_STRING, clipatom, win, now);
  112.  
  113.     timeout.tv_sec = 1;
  114.     timeout.tv_usec = 0;
  115.  
  116.     /* wait for the convertion */
  117.     while (0) {
  118.     int res;
  119.  
  120.     if (XPending(dpy)==0) {
  121.         FD_ZERO(&fdset);
  122.         FD_SET(ConnectionNumber(dpy), &fdset);
  123.         res = select(ConnectionNumber(dpy)+1, &fdset, NULL, NULL,
  124.              &timeout);
  125.         if (res <= 0) {
  126.         ok = 0;
  127.         break;
  128.         }
  129.     }
  130.     if (res > 0 || XPending(dpy) > 0) {
  131.         XNextEvent(dpy, &ev);
  132.         if (ev.type == SelectionNotify && ev.xany.window == win) {
  133.         ok = 1;
  134.         break;
  135.         }
  136.     }
  137.     }
  138.  
  139.     /* if success, return the data */
  140.     if (ok) {
  141.     Atom rtype;
  142.     int bits;
  143.     unsigned long len, bytes;
  144.     unsigned char *data;
  145.  
  146.     if (XGetWindowProperty(dpy, win, clipatom, 0, MAXDATA/4, False, 
  147.                    XA_STRING, &rtype, &bits, &len, &bytes, &data)!=0)
  148.         return NULL;
  149.  
  150.     if ((rtype!=XA_STRING) || (bits!=8)) {
  151.         return NULL;
  152.     } else {
  153.         return (char*)data;
  154.     }
  155.     }
  156.     return NULL;
  157. }
  158.  
  159.  
  160. int
  161. main(int argc, char **argv)
  162. {
  163.     Display *dpy;
  164.     int i, l;
  165.     int buffer=0;
  166.     char *buf;
  167.     int    status;
  168.     char *display_name="";
  169.     char *selection_name=NULL;
  170.  
  171.     for (i=1; i<argc; i++) {
  172.     if (argv[i][0]=='-') {
  173.         if (argv[i][1]=='h' || strcmp(argv[i], "--help")==0) {
  174.         help(argv[0]);
  175.         exit(0);
  176.         } else if (strcmp(argv[i], "--version")==0) {
  177.         puts(PROG_VERSION);
  178.         exit(0);
  179.         } else if (strcmp(argv[i],"-selection")==0
  180.                || strcmp(argv[i],"--selection")==0) {
  181.         if (i<argc-1) {
  182.             selection_name = argv[++i];
  183.         } else {
  184.             selection_name = "PRIMARY";
  185.         }
  186.         } else if (strcmp(argv[i],"-display")==0) {
  187.         if (i<argc-1) {
  188.             display_name = argv[++i];
  189.         } else {
  190.             help(argv[0]);
  191.             exit(0);
  192.         }
  193.         } else if (strcmp(argv[i],"-cutbuffer")==0
  194.                || strcmp(argv[i],"--cutbuffer")==0) {
  195.         if (i<argc-1) {
  196.             i++;
  197.             if (sscanf(argv[i],"%i", &buffer)!=1) {
  198.             fprintf(stderr, "%s: could not convert \"%s\" to int\n", 
  199.                    argv[0], argv[i]);
  200.             exit(1);
  201.             }
  202.             if (buffer<0 || buffer > 7) {
  203.             fprintf(stderr, "%s: invalid buffer number %i\n",
  204.                 argv[0], buffer);
  205.             exit(1);
  206.             }
  207.         } else {
  208.             fprintf(stderr, "%s: invalid argument '%s'\n", argv[0], 
  209.                 argv[i]);
  210.             fprintf(stderr, "Try '%s --help' for more information.\n", 
  211.                 argv[0]);
  212.             exit(1);
  213.         }
  214.         }
  215.     } else {
  216.         fprintf(stderr, "%s: invalid argument '%s'\n", argv[0], argv[i]);
  217.         fprintf(stderr, "Try '%s --help' for more information.\n", 
  218.             argv[0]);
  219.         exit(1);
  220.     }
  221.     }
  222.     dpy = XOpenDisplay(display_name);
  223.     if (!dpy) {
  224.     fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
  225.         XDisplayName(display_name));
  226.     exit(1);
  227.     }
  228.     
  229.     if (selection_name) {
  230.     buf = fetchSelection(dpy, selection_name, argv[0]);
  231.     } else {
  232.     buf = NULL;
  233.     }
  234.  
  235.     if (buf == NULL) {
  236.     buf = XFetchBuffer(dpy, &l, buffer);
  237.     }
  238.  
  239.     if (buf == NULL) {
  240.       status = 1;
  241.     } else {
  242.       if (write(STDOUT_FILENO, buf, l) == -1)
  243.     status = errno;
  244.       else
  245.     status = 0;
  246.     }
  247.     XCloseDisplay(dpy);
  248.     exit(status);
  249. }
  250.  
  251.